import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';

import '../../router/transition/extension.dart';
import '../../router/transition/transition.dart';
import '../../ui/screen/about.dart';
import '../../ui/screen/best_way.dart';
import '../../ui/screen/contact.dart';
import '../../ui/screen/country.dart';
import '../../ui/screen/feedback.dart';
import '../../ui/screen/professional_way.dart';
import '../../ui/screen/web.dart';
import 'common/config.dart';
import 'router/exception/page.dart';
import 'ui/screen/age.dart';
import 'ui/screen/home.dart';
import 'ui/screen/intro.dart';
import 'ui/screen/language.dart';
import 'ui/screen/splash.dart';

final List<RouteBase> _routes = [
  GoRoute(
    path: '/',
    pageBuilder: const SplashScreen().opacity,
  ),
  GoRoute(
    path: '/home',
    pageBuilder: const HomeScreen().opacity,
  ),
  GoRoute(
    path: '/intro',
    pageBuilder: const IntroScreen().opacity,
  ),
  GoRoute(
    path: '/age',
    pageBuilder: const AgeScreen().opacity,
  ),
  GoRoute(
    path: '/language',
    pageBuilder: const LanguageScreen().opacity,
  ),
  GoRoute(
    path: '/country',
    pageBuilder: const CountryScreen().opacity,
  ),
  GoRoute(
    path: '/professional_way',
    pageBuilder: const ProfessionalWayScreen().opacity,
  ),
  GoRoute(
    path: '/best_way',
    pageBuilder: const BestWayScreen().opacity,
  ),
  GoRoute(
    path: '/web',
    pageBuilder: (context, state) => opacityPage(
      child: WebScreen(
        url: Uri.decodeComponent(state.uri.queryParameters['url']!),
        closable: bool.parse(state.uri.queryParameters['closable'] ?? 'false'),
      ),
    ),
  ),
  GoRoute(
    path: '/about',
    pageBuilder: const AboutScreen().opacity,
  ),
  GoRoute(
    path: '/contact',
    pageBuilder: const ContactScreen().opacity,
  ),
  GoRoute(
    path: '/feedback',
    pageBuilder: const FeedbackScreen().opacity,
  ),
];

/// The main app.
class App extends StatelessWidget {
  /// Constructs a [App]
  App({super.key});

  final Config _config = Config();

  late final GoRouter _router = GoRouter(
    onException: (_, GoRouterState state, GoRouter router) {
      router.go('/404', extra: state.uri.toString());
    },
    routes: _routes
      ..add(
        GoRoute(
          path: '/404',
          builder: (BuildContext context, GoRouterState state) {
            return NotFoundScreen(uri: state.extra as String? ?? '');
          },
        ),
      ),
    redirect: (BuildContext context, GoRouterState state) {
      var location = state.matchedLocation;
      if (location == '/' || location == '/web') {
        return null;
      }
      final OnboardingStep step = _config.step;
      switch (step) {
        case OnboardingStep.intro:
          return '/intro';
        case OnboardingStep.age:
          return '/age';
        case OnboardingStep.language:
          return '/language';
        case OnboardingStep.country:
          return '/country';
        case OnboardingStep.none:
          return null;
      }
    },

    // changes on the listenable will cause the router to refresh it's route
    refreshListenable: _config,
  );

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Config>.value(
      value: _config,
      child: MaterialApp.router(
        routerConfig: _router,
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          scaffoldBackgroundColor: const Color(0xFF100D0E),
          colorScheme: const ColorScheme.dark(
            primary: Color(0xFF100D0E),
          ),
          appBarTheme: const AppBarTheme(
            backgroundColor: Color(0xff4744d3),
            titleSpacing: 0,
          ),
          listTileTheme: const ListTileThemeData(
            iconColor: Color(0xff4744d3),
          ),
          buttonTheme: ButtonThemeData(
            buttonColor: const Color(0xff4744d3),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(30),
            ),
          ),
          useMaterial3: true,
        ),
      ),
    );
  }
}
